package com.web.controller;



import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.web.common.Result;
import com.web.entity.RecognitionHistory;
import com.web.service.RecognitionHistoryService;
import com.web.util.MultipartInputStreamFileResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/api/detect")
@CrossOrigin
public class DetectController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RecognitionHistoryService historyService;

    @Autowired
    private ObjectMapper objectMapper;

    @Value("${file.upload.path}")
    private String uploadPath;

    @Value("${file.upload.url}")
    private String uploadUrl;

    @Value("${ai.yolo.service.url:http://localhost:8000}")
    private String yoloServiceUrl;

    @PostMapping("/predict")
    public Result<Map<String, Object>> predict(
            @RequestParam("file") MultipartFile file,
            @RequestParam("userId") Long userId,
            @RequestParam(required = false) String location) {

        try {
            System.out.println("=== 开始处理识别请求 ===");
            System.out.println("文件名: " + file.getOriginalFilename());
            System.out.println("文件大小: " + file.getSize());
            System.out.println("用户ID: " + userId);

            // 1. 保存上传的图片
            String imageUrl = saveUploadFile(file);
            System.out.println("图片保存成功: " + imageUrl);

            // 2. 调用YOLO模型服务
            Map<String, Object> yoloResult = callYoloService(file);

            if (!(Boolean) yoloResult.get("success")) {
                return Result.fail("AI识别失败：" + yoloResult.get("error"));
            }

            // 3. 保存识别记录
            RecognitionHistory history = new RecognitionHistory();
            history.setUserId(userId);
            history.setResult((String) yoloResult.get("result"));
            history.setEnglishName((String) yoloResult.get("english_name"));
            history.setType((String) yoloResult.get("type"));

            // 处理置信度
            Object confidenceObj = yoloResult.get("confidence");
            if (confidenceObj instanceof Double) {
                history.setConfidence(((Double) confidenceObj).intValue());
            } else if (confidenceObj instanceof Integer) {
                history.setConfidence((Integer) confidenceObj);
            }

            history.setImageUrl(imageUrl);
            history.setLocation(location);
            history.setDescription((String) yoloResult.get("description"));
            history.setSuggestion((String) yoloResult.get("suggestion"));

            historyService.saveRecognitionResult(history);

            // 4. 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("history", history);
            result.put("imageUrl", imageUrl);
            result.put("aiResult", yoloResult);

            System.out.println("识别完成: " + yoloResult.get("result"));
            return Result.success("AI识别成功", result);

        } catch (Exception e) {
            System.err.println("识别过程发生错误: " + e.getMessage());
            e.printStackTrace();
            return Result.fail("识别失败：" + e.getMessage());
        }
    }

    /**
     * 调用YOLO服务进行图像识别
     */
    private Map<String, Object> callYoloService(MultipartFile file) throws IOException {
        try {
            System.out.println("=== 调用YOLO服务 ===");
            System.out.println("YOLO服务地址: " + yoloServiceUrl);

            // 调用YOLO服务接口
            String url = yoloServiceUrl + "/predict/";

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("file", new MultipartInputStreamFileResource(
                    file.getInputStream(),
                    file.getOriginalFilename()
            ));

            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);

            System.out.println("YOLO响应状态: " + response.getStatusCode());

            if (response.getStatusCode() == HttpStatus.OK) {
                // 解析JSON响应
                JsonNode jsonNode = objectMapper.readTree(response.getBody());
                Map<String, Object> result = objectMapper.convertValue(jsonNode, Map.class);
                System.out.println("YOLO识别结果: " + result);
                return result;
            } else {
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("success", false);
                errorResult.put("error", "YOLO服务调用失败，状态码: " + response.getStatusCode());
                return errorResult;
            }

        } catch (Exception e) {
            System.err.println("调用YOLO服务失败: " + e.getMessage());
            e.printStackTrace();
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("error", "调用YOLO服务时发生错误: " + e.getMessage());
            return errorResult;
        }
    }

    /**
     * 健康检查接口
     */
    @GetMapping("/health")
    public Result<Map<String, Object>> healthCheck() {
        try {
            String url = yoloServiceUrl + "/health";
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

            if (response.getStatusCode() == HttpStatus.OK) {
                JsonNode jsonNode = objectMapper.readTree(response.getBody());
                Map<String, Object> result = objectMapper.convertValue(jsonNode, Map.class);
                return Result.success("YOLO服务状态正常", result);
            } else {
                return Result.fail("YOLO服务不可用");
            }
        } catch (Exception e) {
            return Result.fail("无法连接到YOLO服务: " + e.getMessage());
        }
    }

    /**
     * 🔧 修正文件保存方法
     */
    private String saveUploadFile(MultipartFile file) throws IOException {
        try {
            System.out.println("=== 保存上传文件 ===");
            System.out.println("配置的上传路径: " + uploadPath);

            // 生成唯一文件名
            String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
            System.out.println("生成的文件名: " + fileName);

            // 🔧 确保上传目录存在
            Path uploadDir = Paths.get(uploadPath);
            if (!Files.exists(uploadDir)) {
                Files.createDirectories(uploadDir);
                System.out.println("创建上传目录: " + uploadDir.toAbsolutePath());
            }

            // 保存文件
            Path filePath = uploadDir.resolve(fileName);
            Files.copy(file.getInputStream(), filePath);

            String fileUrl = uploadUrl + fileName;
            System.out.println("文件保存成功: " + filePath.toAbsolutePath());
            System.out.println("文件访问URL: " + fileUrl);

            return fileUrl;

        } catch (IOException e) {
            System.err.println("文件保存失败: " + e.getMessage());
            e.printStackTrace();
            throw new IOException("文件保存失败: " + e.getMessage(), e);
        }
    }
}
